#include <stdio.h>

#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>

#include "func_file.h"

int func_file_get_size(char *filePath)
{
    // 校验传入的文件路径是否为空指针
    if (filePath == NULL)
    {
        printf("[%s:%d][error]filePath is NULL!\n", __FUNCTION__, __LINE__);
        return -1;
    }

    // 尝试以二进制模式打开文件
    FILE *pFile = fopen(filePath, "rb");
    if (pFile == NULL)
    {
        printf("[%s:%d][error]fopen %s fail!\n", __FUNCTION__, __LINE__, filePath);
        return -1;
    }

    // 定位到文件末尾并获取文件大小
    if (fseek(pFile, 0, SEEK_END) != 0)
    {
        printf("[%s:%d][error]fseek %s fail!\n", __FUNCTION__, __LINE__, filePath);
        fclose(pFile);
        return -1;
    }

    long size = ftell(pFile);
    if (size == -1L)
    {
        printf("[%s:%d][error]ftell %s fail!\n", __FUNCTION__, __LINE__, filePath);
        fclose(pFile);
        return -1;
    }

    // 关闭文件并返回结果
    fclose(pFile);
    return (int)size;
}

int func_file_write(unsigned int mode, char *filePath, void *addr, int len)
{
    int   ret = -1;
    FILE *fp = NULL;

    if (NULL == filePath || NULL == addr || 0 == len)
    {
        printf("[%s:%d][error]filePath:%p, addr:%p, len:%d\n", __FUNCTION__, __LINE__, filePath, addr, len);
        return -1;
    }

    if (0 == mode) // 生成新的文件
    {
        fp = fopen(filePath, "wb");
    }
    else if (2 == mode) // 追加到文件尾
    {
        fp = fopen(filePath, "a");
    }
    else if (3 == mode)
    {
        fp = fopen(filePath, "ab+");
    }
    else if (4 == mode)
    {
        int fdTest = 0;
        fdTest = open(filePath, O_RDWR);
        if (fdTest != -1)
        {
            write(fdTest, (char *)addr, len);
            close(fdTest);
        }
        else
        {
            printf("[%s:%d][error]open %s fail!\n", __FUNCTION__, __LINE__, filePath);
        }
        return ret;
    }

    if (NULL != fp)
    {
        ret = fwrite((char *)addr, 1, len, fp);
        if (ret != len)
        {
            printf("[%s:%d][error]fwrite file failed!ret:%d,len:%d!\n", __FUNCTION__, __LINE__, ret, len);
            ret = -2;
        }
        fflush(fp);
        fclose(fp);
    }
    else
    {
        printf("[%s:%d][error]fopen %s fail!\n", __FUNCTION__, __LINE__, filePath);
    }

    return ret;
}

int func_file_read(char *filePath, void *addr, unsigned int bufMaxLen, unsigned int *pRLen)
{
    FILE        *fp = NULL;
    unsigned int file_size = 0;
    unsigned int loadLen = 0;
    unsigned int rLen = 0;

    if (NULL == filePath || NULL == addr)
    {
        printf("[%s:%d][error]filePath:%p, addr:%p\n", __FUNCTION__, __LINE__, filePath, addr);
        return -1;
    }

    fp = fopen(filePath, "rb");
    if (NULL == fp)
    {
        printf("[%s:%d][error]fopen %s fail!\n", __FUNCTION__, __LINE__, filePath);
        return -1;
    }
    // 获取文件大小
    fseek(fp, 0, SEEK_END);
    file_size = ftell(fp);
    if (file_size > bufMaxLen)
    {
        loadLen = bufMaxLen;
    }
    else
    {
        loadLen = file_size;
    }
    if (loadLen == 0)
    {
        printf("[%s:%d][error]ftell %s fail!loadLen:%d, bufMaxLen:%d\n", __FUNCTION__, __LINE__, filePath, loadLen,
               bufMaxLen);
        fclose(fp);
        return -1;
    }
    // 从头开始读取文件
    fseek(fp, 0, SEEK_SET);
    rLen = fread(addr, 1, loadLen, fp);
    fclose(fp);
    if (rLen != loadLen)
    {
        printf("[%s:%d][error]fread %s fail!rLen:%d, loadLen:%d\n", __FUNCTION__, __LINE__, filePath, rLen, loadLen);
        return -1;
    }
    printf("[success]fread size %d from %s!loadLen:%d\n", rLen, filePath, loadLen);
    if (pRLen != NULL)
    {
        *pRLen = loadLen;
    }
    return 0;
}
